home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OWLSRC.PAK / EDITFILE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  9.2 KB  |  389 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1992, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.9  $
  6. //
  7. // Implementation of class TEditFile, a text edit which can find/replace and
  8. // read/write from/to a file.
  9. //----------------------------------------------------------------------------
  10. #pragma hdrignore SECTION
  11. #include <owl/pch.h>
  12. #if !defined(OWL_WINDOW_H)
  13. # include <owl/window.h>
  14. #endif
  15. #if !defined(OWL_CONTROL_H)
  16. # include <owl/control.h>
  17. #endif
  18. #if !defined(OWL_EDIT_H)
  19. # include <owl/edit.h>
  20. #endif
  21. #if !defined(OWL_EDITSEAR_H)
  22. # include <owl/editsear.h>
  23. #endif
  24. #if !defined(OWL_EDITFILE_H)
  25. # include <owl/editfile.h>
  26. #endif
  27. #if !defined(OWL_APPLICAT_H)
  28. # include <owl/applicat.h>
  29. #endif
  30. #if !defined(WINSYS_SYSTEM_H)
  31. # include <winsys/system.h>
  32. #endif
  33. #include <string.h>
  34. #include <limits.h>
  35. #include <stdio.h>
  36.  
  37. OWL_DIAGINFO;
  38.  
  39. #if !defined(SECTION) || SECTION == 1
  40.  
  41. DEFINE_RESPONSE_TABLE1(TEditFile, TEditSearch)
  42.   EV_COMMAND(CM_FILESAVE, CmFileSave),
  43.   EV_COMMAND(CM_FILESAVEAS, CmFileSaveAs),
  44.   EV_COMMAND_ENABLE(CM_FILESAVE, CmSaveEnable),
  45. END_RESPONSE_TABLE;
  46.  
  47. //
  48. // constructor for a TEditFile
  49. //
  50. // initializes its data members using passed parameters and default values
  51. //
  52. TEditFile::TEditFile(TWindow*        parent,
  53.                      int             id,
  54.                      const char far* text,
  55.                      int x, int y, int w, int h,
  56.                      const char far* fileName,
  57.                      TModule*        module)
  58. :
  59.   TEditSearch(parent, id, text, x, y, w, h, module)
  60. {
  61.   FileName = fileName ? strnewdup(fileName) : 0;
  62. }
  63.  
  64. //
  65. // dispose of the file name
  66. //
  67. TEditFile::~TEditFile()
  68. {
  69.   delete[] FileName;
  70. }
  71.  
  72. //
  73. // performs setup for a TEditFile
  74. //
  75. void
  76. TEditFile::SetupWindow()
  77. {
  78.   TEditSearch::SetupWindow();
  79.   FileData.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
  80.  
  81. #if defined(BI_PLAT_WIN32)
  82.   FileData.Flags |= OFN_LONGNAMES;
  83.   //
  84.   // We currently cannot mix OFN_ENABLEHOOK & OFN_EXPLORER
  85.   // when running under NT 3.51[no new shell]
  86.   //
  87.   if (TSystem::Has3dUI())
  88.     FileData.Flags |= OFN_EXPLORER;
  89. #endif
  90.  
  91.   FileData.SetFilter(GetModule()->LoadString(IDS_FILEFILTER).c_str());
  92.  
  93.   SetFileName(FileName);
  94.   if (FileName && !Read()) {
  95.     string msgTemplate(GetModule()->LoadString(IDS_UNABLEREAD));
  96.     char*  msg = new char[_MAX_PATH + msgTemplate.length()];
  97.     sprintf(msg, msgTemplate.c_str(), FileName);
  98.     MessageBox(msg, GetApplication()->GetName(), MB_ICONEXCLAMATION | MB_OK);
  99.     delete[] msg;
  100.     SetFileName(0);
  101.   }
  102. }
  103.  
  104. //
  105. // sets the file name of the window and updates the caption
  106. // replacing an empty name with 'Untitled' in its caption
  107. //
  108. void
  109. TEditFile::SetFileName(const char far* fileName)
  110. {
  111.   if (fileName != FileName) {
  112.     delete[] FileName;
  113.     FileName = fileName ? strnewdup(fileName) : 0;
  114.   }
  115.   string untitled(GetModule()->LoadString(IDS_UNTITLEDFILE));
  116.   SetDocTitle(FileName ? (const char far*)FileName : untitled.c_str(), 0);
  117. }
  118.  
  119. //
  120. // begins the edit of a new file, after determining that it is Ok to
  121. // clear the TEdit's text
  122. //
  123. void
  124. TEditFile::NewFile()
  125. {
  126.   if (CanClear()) {
  127.     Clear();
  128.     Invalidate();
  129.     ClearModify();
  130.     SetFileName(0);
  131.   }
  132. }
  133.  
  134. //
  135. // replaces the current file with the given file
  136. //
  137. void
  138. TEditFile::ReplaceWith(const char far* fileName)
  139. {
  140.   if (Read(fileName)) {
  141.     Invalidate();
  142.     SetFileName(fileName);
  143.   }
  144.   else {
  145.     string msgTemplate(GetModule()->LoadString(IDS_UNABLEREAD));
  146.     char*  msg = new char[_MAX_PATH + msgTemplate.length()];
  147.     sprintf(msg, msgTemplate.c_str(), fileName);
  148.     MessageBox(msg, GetApplication()->GetName(), MB_ICONEXCLAMATION | MB_OK);
  149.     delete[] msg;
  150.   }
  151. }
  152.  
  153. //
  154. // brings up a dialog allowing the user to open a file into this
  155. // window
  156. //
  157. // same as selecting File|Open from the menus
  158. //
  159. void
  160. TEditFile::Open()
  161. {
  162.   if (CanClear()) {
  163.     *FileData.FileName = 0;
  164.     if (TFileOpenDialog(this, FileData).Execute() == IDOK)
  165.       ReplaceWith(FileData.FileName);
  166.   }
  167. }
  168.  
  169. //
  170. // reads the contents of a  specified file, or the previously-specified file
  171. // if no name passed, into the TEdit control
  172. // The caller is responsible for any error UI
  173. //
  174. bool
  175. TEditFile::Read(const char far* fileName)
  176. {
  177.   if (!fileName)
  178.     if (FileName)
  179.       fileName = FileName;
  180.     else
  181.       return false;
  182.  
  183.   bool   success = false;
  184.   HFILE  file = _lopen(fileName, OF_READ);
  185.  
  186.   if (file != HFILE_ERROR) {
  187.     long  charsToRead = _llseek(file, 0, SEEK_END);
  188.     _llseek(file, 0, SEEK_SET);
  189.  
  190.     if (charsToRead >= 0
  191. #if !defined(BI_PLAT_WIN32)
  192.         && charsToRead < UINT_MAX     // limit 16bit edit ctrls to 1 segment
  193. #endif
  194.       ) {
  195.       Clear();
  196.  
  197.       // Lock and resize Editor's buffer to the size of the file
  198.       // Then if OK, read the file into editBuffer
  199.       //
  200.       char far* editBuffer = LockBuffer(uint(charsToRead+1));
  201.       if (editBuffer) {
  202.         if (_lread(file, editBuffer, uint(charsToRead)) == uint(charsToRead)) {
  203.  
  204.           // 0 terminate Editor's buffer
  205.           //
  206.           editBuffer[int(charsToRead)] = 0;
  207.           success = true;
  208.           ClearModify();
  209.         }
  210.         UnlockBuffer(editBuffer, true);
  211.       }
  212.     }
  213.     _lclose(file);
  214.   }
  215.  
  216.   return success;
  217. }
  218.  
  219. //
  220. // saves the contents of the TEdit child control into the file currently
  221. // being editted
  222. //
  223. // returns true if the file was saved or IsModified returns false
  224. //(contents already saved)
  225. //
  226. bool
  227. TEditFile::Save()
  228. {
  229.   if (IsModified()) {
  230.     if (!FileName)
  231.       return SaveAs();
  232.  
  233.     if (!Write()) {
  234.       string msgTemplate(GetModule()->LoadString(IDS_UNABLEWRITE));
  235.       char*  msg = new char[_MAX_PATH + msgTemplate.length()];
  236.       sprintf(msg, msgTemplate.c_str(), FileName);
  237.       MessageBox(msg, GetApplication()->GetName(), MB_ICONEXCLAMATION | MB_OK);
  238.       delete[] msg;
  239.       return false;
  240.     }
  241.   }
  242.   return true;  // editor's contents haven't been changed
  243. }
  244.  
  245. //
  246. // saves the contents of the TEdit child control into a file whose name
  247. // is retrieved from the user, through execution of a "Save" file dialog
  248. //
  249. // returns true if the file was saved
  250. //
  251. bool
  252. TEditFile::SaveAs()
  253. {
  254.   if (FileName)
  255.     strcpy(FileData.FileName, FileName);
  256.  
  257.   else
  258.     *FileData.FileName = 0;
  259.  
  260.   if (TFileSaveDialog(this, FileData).Execute() == IDOK) {
  261.     if (Write(FileData.FileName)) {
  262.       SetFileName(FileData.FileName);
  263.       return true;
  264.     }
  265.     string msgTemplate(GetModule()->LoadString(IDS_UNABLEWRITE));
  266.     char*  msg = new char[_MAX_PATH + msgTemplate.length()];
  267.     sprintf(msg, msgTemplate.c_str(), FileName);
  268.     MessageBox(msg, GetApplication()->GetName(), MB_ICONEXCLAMATION | MB_OK);
  269.     delete[] msg;
  270.   }
  271.   return false;
  272. }
  273.  
  274. //
  275. // Enables save command only if text is modified
  276. //
  277. void
  278. TEditFile::CmSaveEnable(TCommandEnabler& commandHandler)
  279. {
  280.   commandHandler.Enable(IsModified());
  281. }
  282.  
  283. //
  284. // writes the contents of the TEdit child control to a specified file, or
  285. // the previously-specified file if none passed.
  286. // The caller is responsible for any error UI
  287. //
  288. bool
  289. TEditFile::Write(const char far* fileName)
  290. {
  291.   if (!fileName)
  292.     if (FileName)
  293.       fileName = FileName;
  294.     else
  295.       return false;
  296.  
  297.   int file = _lcreat(fileName, 0);
  298.   if (file == -1) {
  299.     return false;
  300.   }
  301.  
  302.   bool success = false;
  303.   char far* editBuffer = LockBuffer();
  304.   if (editBuffer) {
  305.     success = ToBool(_lwrite(file, editBuffer, strlen(editBuffer)) != (uint16)-1);
  306.     UnlockBuffer(editBuffer);
  307.     if (success)
  308.       ClearModify();
  309.   }
  310.   _lclose(file);
  311.  
  312.   return success;
  313. }
  314.  
  315. //
  316. // returns a bool value indicating whether or not it is Ok to clear
  317. // the TEdit's text
  318. //
  319. // returns true if the text has not been changed, or if the user Oks the
  320. // clearing of the text
  321. //
  322. bool
  323. TEditFile::CanClear()
  324. {
  325.   if (IsModified()) {
  326.     string msgTemplate(GetModule()->LoadString(IDS_FILECHANGED));
  327.     string untitled(GetModule()->LoadString(IDS_UNTITLEDFILE));
  328.     char*  msg = new char[_MAX_PATH+msgTemplate.length()];
  329.  
  330.     sprintf(msg, msgTemplate.c_str(),
  331.              FileName ? (const char far*)FileName : untitled.c_str());
  332.  
  333.     int result = MessageBox(msg, GetApplication()->GetName(), MB_YESNOCANCEL|MB_ICONQUESTION);
  334.     delete[] msg;
  335.     return result==IDYES ? Save() : result != IDCANCEL;
  336.   }
  337.   return true;
  338. }
  339.  
  340. //
  341. //
  342. //
  343. bool
  344. TEditFile::CanClose()
  345. {
  346.   return CanClear();
  347. }
  348.  
  349. #endif
  350. #if !defined(SECTION) || SECTION == 2
  351.  
  352.  
  353. IMPLEMENT_STREAMABLE1(TEditFile, TEditSearch);
  354.  
  355. #if !defined(BI_NO_OBJ_STREAMING)
  356.  
  357. //
  358. // reads an instance of TEditFile from the passed ipstream
  359. //
  360. void*
  361. TEditFile::Streamer::Read(ipstream& is, uint32 /*version*/) const
  362. {
  363.   TEditFile* o = GetObject();
  364.   ReadBaseObject((TEditSearch*)o, is);
  365.  
  366.   o->FileName = is.freadString();
  367.   if (!*o->FileName) {
  368.     delete o->FileName;
  369.     o->FileName = 0;
  370.   }
  371.   return o;
  372. }
  373.  
  374. //
  375. // writes the TEditFile to the passed opstream
  376. //
  377. void
  378. TEditFile::Streamer::Write(opstream& os) const
  379. {
  380.   TEditFile* o = GetObject();
  381.   WriteBaseObject((TEditSearch*)o, os);
  382.   os.fwriteString(o->FileName ? o->FileName : "");
  383. }
  384.  
  385. #endif  // if !defined(BI_NO_OBJ_STREAMING)
  386.  
  387. #endif
  388.  
  389.